package src.xio.ccf_201612;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
//授权，用户，角色，权限 100分
public class PrivilegeQuery {
    private static List<Privi> priList = new ArrayList<>(); //存储题目中P段的权限；其实啥用没有
    private static List<User> usList = new ArrayList<User>(); //存储用户
    private static HashMap<String,List<Privi>> roMap = new HashMap<>(); //存储角色（角色名及其权限列表）

    private static final String TRUE = "true"; //方便统一打印输出
    private static final String FALSE = "false";

    public static void main(String[] args){

        Scanner sc = new Scanner(System.in);

        //解析P段权限；没啥用
        int priliNum = sc.nextInt();//权限数量
        for (int i = 0; i <priliNum ; i++) {
            priList.add(new Privi(sc.next()));
        }

        //解析R段角色；这里用map来存是为了方便后面直接根据角色名字来取对应的权限列表
        int roleNum=sc.nextInt();//角色数量
        for (int i = 0; i <roleNum ; i++) {
           String roleName = sc.next(); //角色名
            int r=sc.nextInt();//角色里面的权限个数
            List<Privi> tmpList = new ArrayList<>(r);
            for (int j = 0; j <r; j++) {
                tmpList.add(new Privi(sc.next()));
            }
            roMap.put(roleName,tmpList);//角色名及其对应的权限列表
        }

        //解析 U 段用户；这里每个用户存储的不再是用户名和其包含的角色名，而是再深入解析了一步，存的是用户名和其包含的权限！
        int userNum=sc.nextInt();//用户个数
        for (int i = 0; i <userNum; i++) {
            User us = new User(sc.next());
            int u=sc.nextInt();//用户里面的角色个数
            for (int j = 0; j <u ; j++) {
                String tmpR = sc.next(); //用户包含的角色名
                List<Privi> tmpPrivi = roMap.get(tmpR); //去前面角色map里找名字对应的权限列表
                for (Privi p : tmpPrivi) {
                    us.putPrivi(p); //存储权限；这里对同名不同等级的权限做了判断，保留等级最大的
                }
            }
            usList.add(us);
        }

        // 解析 Q 段待查询用户
        int s=sc.nextInt();//查询权限数量
        List<Query> queryList = new ArrayList<Query>();
        for (int i = 0; i <s; i++) {
           Query qu=new Query(sc.next(), sc.next());
            queryList.add(qu);
        }
        //执行查询操作
        for (Query query:queryList) {
            System.out.println(check(query));
        }
        sc.close();
    }
    //查询用户是否有这个权限
    private static String check(Query qu){
        //先查有没有这个用户名
        User queryUs = null;//查到的 U 段的用户
        for (User us:usList){
            if (us.name.equals(qu.name)){
                queryUs = us;
                break;
            }
        }
        if (queryUs == null){ // U 段里没查到，这是没有这个用户名了
            return FALSE;
        }
        //查到了
        Privi quPrivi = qu.privi; //待查询的用户的权限
        HashMap<String,Integer> map = queryUs.getPriviMap();//查到的U 段用户的权限列表；<权限名，等级>
        Integer stLevel = map.get(quPrivi.name);
       if (stLevel == null){ // 查到的等级为null，说明压根不存在这个权限 (Integer 是包装类型（默认null），不是基础类型int(默认0))
           return FALSE;
       } else {
           if (quPrivi.level == -1){ //待查询的用户的权限不带等级
                if (stLevel != -1){
                    return stLevel+""; //查到的带等级，返回这个等级
                }
                return TRUE; //查到的也不带等级
           }else {
               if (stLevel != -1 && quPrivi.level <= stLevel){
                   return TRUE;
               }
               return FALSE;
           }
       }
    }

    //权限
    static class Privi{
        String name;
        int level;
        Privi(String per){
            String []a=per.split(":");
            if (a.length==1){
                this.name = a[0];
                this.level=-1;//未说明权限时，设为-1
            }else if (a.length==2){
                this.name = a[0];//有权限时，权限等级大于1
                this.level = Integer.parseInt(a[1]);
            }
        }
    }

    //用户
    static class User{
        String name;
        HashMap<String,Integer> priviMap; //存的是权限名和等级；因为有通过名字来找等级的需求，map更方便，所以不存Privi
        User(String n){
            this.name=n;
            this.priviMap = new HashMap<>();
        }

        HashMap<String,Integer> getPriviMap() {
            return priviMap;
        }

        void putPrivi(Privi r){
           if (priviMap.containsKey(r.name)){ //map里已经有了这个名字的权限了，需要进一步比较等级大小
               int tmp = priviMap.get(r.name);
               if (r.level > tmp){ //谁等级大存谁
                   priviMap.put(r.name,r.level);
               }
           }else { //map里还没有了这个名字的权限，直接进去
               priviMap.put(r.name,r.level);
           }
        }
    }

    //待查询用户
    static class Query{
        String name;
        Privi privi;

        Query(String name, String pri) {
            this.name = name;
            this.privi =new Privi(pri);
        }
    }
}
